package cn.doways.api.service.serviceimpl;

import cn.doways.api.dto.*;
import cn.doways.api.entity.Student;
import cn.doways.api.entity.WeekTime;
import cn.doways.api.mapper.UsersMapper;
import cn.doways.api.repository.SignMongoDB;
import cn.doways.api.service.TransactionService;
import cn.doways.api.utils.DateUtils;
import cn.doways.api.utils.ListUtils;
import cn.doways.api.vo.LateListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @ClassName TransactionServiceImpl
 * @Description //TODO
 * @Author shellming
 * @Date 2019-08-28 22:38
 **/
@Service
public class TransactionServiceImpl implements TransactionService {
    private UsersMapper usersMapper;
    private Student student;
    private SignCourseDTO signCourseDTO;
    private SignMongoDB signMongoDB;
    private SaveSignDTO saveSignDTO;
    private static final String SALT = "1^uaR$D2!eKUjYhBEwOf3qY9er&bMnrsg@O#eg$9Ho3I8@FBC8Q%@Awmi6b!ANoE";

    @Autowired
    public TransactionServiceImpl(UsersMapper usersMapper, Student student, SignCourseDTO signCourseDTO, SignMongoDB signMongoDB, SaveSignDTO saveSignDTO) {
        this.usersMapper = usersMapper;
        this.student = student;
        this.signCourseDTO = signCourseDTO;
        this.signMongoDB = signMongoDB;
        this.saveSignDTO = saveSignDTO;

    }

    @Override
    public Result<String> signCheckTransaction(SignDTO signDTO) {
        //获取学生信息
        student = usersMapper.getMajorClassidAndGrade(signDTO.getId());
        int week = LocalDateTime.now()
                    .getDayOfWeek()
                    .getValue();
        //获取课程信息
        signCourseDTO = usersMapper.getSignCourse(student.getMajor(), student.getGrade(), student.getClassId(), week, signDTO.getTimeId());
        //获得现在时间和课程开始结束时间
        LocalTime now = LocalTime.now();
        LocalTime start = DateUtils.getLocalTime(signCourseDTO.getStartTime()).minusMinutes(5L);
        LocalTime end = DateUtils.getLocalTime(signCourseDTO.getStartTime()).plusMinutes(15L);
        //判断是否在正确时间正确地点
        if (now.isBefore(start)) {
            return Result.error("不要提前签到呦～！");
        } else if (now.isAfter(end)) {
            return Result.error("签到已结束");
        } else if (signDTO.getBuildingUuid().equals(signCourseDTO.getBuildingUuid()) && signDTO.getFloorsMajor().equals(signCourseDTO.getFloorsMajor()) && signDTO.getRoomMinor().equals(signCourseDTO.getRoomMinor())) {
            return Result.success(DigestUtils.md5DigestAsHex((signDTO.getId() + signDTO.getBuildingUuid() + signDTO.getRoomMinor() + signDTO.getFloorsMajor() + signDTO.getTimeId() + SALT).getBytes()));
        } else {
            return Result.error("大兄弟你来错教室了～！");
        }
    }

    @Override
    public Result<String> signTransaction(SignDTO signDTO) {
        //获得学期开始时间
        WeekTime weekTime = usersMapper.getWeekTime(1, 2019, 2020);
        //当前日期是开学第几周
        int justWeek = DateUtils.getJustWeek(
                DateUtils.asLocalDateTime(weekTime.getStartWeek()),
                LocalDateTime.now()
        )+1;
        //检查MD5值和人脸分数是否符合要求
        if (!DigestUtils.md5DigestAsHex((signDTO.getId() + signDTO.getBuildingUuid() + signDTO.getRoomMinor() + signDTO.getFloorsMajor() + signDTO.getTimeId() + SALT).getBytes()).equals(signDTO.getMd5())) {
            return Result.error("篡改数据");
        } else if (signDTO.getScore() <= 80f) {
            return Result.error("人脸信息有误！");
        } else {
            //获得今天周几
            int week = LocalDateTime.now()
                    .getDayOfWeek()
                    .getValue();
            //获得要签到的课程信息
            student = usersMapper.getMajorClassidAndGrade(signDTO.getId());
            saveSignDTO = usersMapper.getSaveSign(student.getMajor(), student.getGrade(), student.getClassId(), week, signDTO.getTimeId());
            signCourseDTO = usersMapper.getSignCourse(student.getMajor(),student.getGrade(),student.getClassId(),week,saveSignDTO.getTimeId());
            System.out.println("saveSignDTO  "+saveSignDTO.toString());
            saveSignDTO.setJustWeek(justWeek);
            //查询mongodb是否有课程信息
            saveSignDTO = signMongoDB.queryById(saveSignDTO.getMajorId(), saveSignDTO.getClassId(), saveSignDTO.getCourseId(), saveSignDTO.getTeacherId(), saveSignDTO.getTimeId(), saveSignDTO.getWeek(), saveSignDTO.getBuildingUuid(), saveSignDTO.getFloorsMajor(), saveSignDTO.getRoomMinor(), saveSignDTO.getJustWeek());
            //获得签到时间
            LocalTime now = LocalTime.now();
            //获得课程开始时间
            LocalTime start = DateUtils.getLocalTime(signCourseDTO.getStartTime());
            //检查mongoDB的课程信息是否为空
            if (saveSignDTO == null) {
                //创建上课学生列表
                List<SignStudentDTO> list = usersMapper.getClassStudent(student.getGrade(), student.getMajor(), student.getClassId());
                //获取课程信息
                saveSignDTO = usersMapper.getSaveSign(student.getMajor(), student.getGrade(), student.getClassId(), week, signDTO.getTimeId());
                LocalDate localDate = LocalDate.now();
                //便利学生列表判断拉起列表人是否迟到
                for (SignStudentDTO signStudentDTO : list) {
                    //除拉起签到的人以外的所有人设为旷课
                    if (usersMapper.getLeaveForSign(signStudentDTO.getId(),DateUtils.asDate(localDate)).size()>0){
                        List<GetLeaveForSign> leaveForSigns= usersMapper.getLeaveForSign(signStudentDTO.getId(),DateUtils.asDate(localDate));
                        for (GetLeaveForSign getLeaveForSign : leaveForSigns){
                            if (saveSignDTO.getTimeId()>=getLeaveForSign.getStartNumber()&&saveSignDTO.getTimeId()<=getLeaveForSign.getEndNumber()){
                                signStudentDTO.setStatus(getLeaveForSign.getLeaveReason());
                            }else {
                                signStudentDTO.setStatus(0);
                            }
                        }
                    }else {
                        signStudentDTO.setStatus(0);
                    }
                    if (signStudentDTO.getId().equals(signDTO.getId())) {
                        if (now.isAfter(start)) {
                            signStudentDTO.setStatus(2);
                        } else {
                            signStudentDTO.setStatus(1);
                        }
                    }

                }
                //单例复用更新列表
                saveSignDTO.setStudentlist(list);
                //设置开学后第几周
                saveSignDTO.setJustWeek(justWeek);
                //保存到mongoDB
                signMongoDB.save(saveSignDTO);
                return Result.success(1 + "");
            } else {
                //遍历学生列表拦截重复签到
                for (SignStudentDTO signStudentDTO : saveSignDTO.getStudentlist()) {
                    if (signStudentDTO.getId().equals(signDTO.getId())) {
                        if (signStudentDTO.getStatus() != 0) {
                            return Result.error("不要重复签到！");
                        }
                    }
                }
                //判断是否迟到
                if (now.isAfter(start)) {
                    for (SignStudentDTO signStudentDTO : saveSignDTO.getStudentlist()) {
                        if (signStudentDTO.getId().equals(signDTO.getId())) {
                            signStudentDTO.setStatus(2);
                        }
                    }
                    List<SignStudentDTO> list = saveSignDTO.getStudentlist();
                    String id = saveSignDTO.getId();
                    signMongoDB.updateStudentList(id, list);
                    return Result.success("你迟到了");
                } else {
                    for (SignStudentDTO signStudentDTO : saveSignDTO.getStudentlist()) {
                        if (signStudentDTO.getId().equals(signDTO.getId())) {
                            signStudentDTO.setStatus(1);
                        }
                    }
                    List<SignStudentDTO> list = saveSignDTO.getStudentlist();
                    String id = saveSignDTO.getId();
                    signMongoDB.updateStudentList(id, list);
                    return Result.success("签到成功");
                }

            }

        }

    }

    @Override
    public Result<String> doLeaveTransaction(LeaveRequestDTO leaveRequestDTO) {
        LocalDate localDate=DateUtils.asLocalDate(leaveRequestDTO.getLeaveDate());
        List<LeaveCheckDTO> list = usersMapper.getLeaveCheck(leaveRequestDTO.getStudentId(),DateUtils.asDate(localDate));
        if (list.size() > 0) {
            for (LeaveCheckDTO leaveCheckDTO : list) {
                if (leaveCheckDTO.getStartNumber() >= leaveRequestDTO.getStartNumber() && leaveCheckDTO.getEndNumber() <= leaveRequestDTO.getEndNumber()) {
                    return Result.error("不要重复请假！");
                }
            }
        } else {
            Student student=usersMapper.getMajorClassidAndGrade(leaveRequestDTO.getStudentId());
            leaveRequestDTO.setClassId(student.getClassId());
            leaveRequestDTO.setMajorId(student.getMajor());
            leaveRequestDTO.setGrade(student.getGrade());
            leaveRequestDTO.setTimestamp(DateUtils.asDate(LocalDateTime.now()));
            int result = usersMapper.doLeaveApplication(leaveRequestDTO);
            if (result == 1) {
                return Result.success(result + "");
            }

        }

        return Result.error("MySQL异常");
    }


    @Override
    public Result<List<String>> getTodayClassId(String id,String date) {
        if (id.length()==0|| StringUtils.isEmpty(id)||usersMapper.hasStudent(id)==0){
            return Result.error(null);
        }else {
            Student student=usersMapper.getMajorClassidAndGrade(id);
            LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            int week= localDate.getDayOfWeek().getValue();
            WeekTime weekTime=usersMapper.getWeekTime(1,2019,2020);
            int justWeek=DateUtils.getJustWeekDate(
                    DateUtils.asLocalDate(weekTime.getStartWeek()),
                    localDate
            )+1;
            if (usersMapper.getTodayClassId(student.getGrade(),student.getMajor(),student.getClassId(),week,justWeek).size()>0){
                return Result.success(usersMapper.getTodayClassId(student.getGrade(),student.getMajor(),student.getClassId(),week,justWeek));
            }else {
                return Result.error("今天没课不需要请假");
            }

        }
    }

    @Override
    public Result<List<LateListVO>> getLateList(String id) {
        if (usersMapper.hasStudent(id)==0){
            return Result.error("没有此学生");
        }else {
            //NULL

            Student student=usersMapper.getMajorClassidAndGrade(id);
            List<LateListVO> list=ListUtils.getList(usersMapper.getLateList(id),
                                                    signMongoDB.getAbsent(student.getGrade(), student.getMajor(), student.getClassId(), id),
                                                    id,
                                                    DateUtils.asLocalDate(usersMapper.getWeekTime(1,2019,2020).getStartWeek())
                                                   );
            return Result.success(list);
        }

    }


}
